<template>
  <div>
    <div>
      <span>搜索地址：</span>
      <el-autocomplete
          v-model="keywords"
          style="width: 300px;margin-bottom: 10px"
          :fetch-suggestions="querySearchAsync"
          placeholder="请输入内容"
          @select="searchAddress"
      ></el-autocomplete>
      <span style="margin-left: 10px">
          <span>经度：{{ form.lon }}</span>
          <span style="margin-left: 10px">纬度：{{ form.lat }}</span>
          <span style="margin-left: 10px">地址：{{form.address}}</span>
        </span>
    </div>
    <div id="map-container"></div>
    <div id="popup-box" class="popup-box">
      <button id="close-button" class="close-button">&times;</button>
      <div id="popup-content" class="popup-content"></div>
    </div>
  </div>
</template>
<script>
import {Map,View,Feature} from 'ol'
import { Tile as TileLayer } from 'ol/layer'
import { get } from 'ol/proj';
import { getWidth, getTopLeft } from 'ol/extent'
import { WMTS } from 'ol/source'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import { defaults as defaultControls} from 'ol/control';
import { search} from '@/api/map'
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import {Point} from "ol/geom";
import {Icon, Style} from "ol/style";
import Overlay from 'ol/Overlay';

export const projection = get("EPSG:4326");
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = [];
for (let z = 0; z < 19; ++z) {
  resolutions[z] = size / Math.pow(2, z);
}
const TIAN_DI_KEY = '你申请的KEY';
export default {
  data() {
    return {
      map:null,
      keywords:'',
      // 搜索提示信息
      options: [],
      // 位置信息
      form: {
        lon: '',
        lat: '',
        address:'',
      },
      pointLayer: new VectorLayer({
        source: new VectorSource(),
      }),
      feature:null,
    }
  },
  mounted(){
    this.initMap() // 加载矢量底图
  },
  methods:{
    initMap() {
      this.map = new Map({
        target: 'map-container',
        layers: [
          // 底图
          new TileLayer({
            source: new WMTS({
              url: `http://t{0-6}.tianditu.com/vec_c/wmts?tk=${TIAN_DI_KEY}`,
              layer: 'vec', // 矢量底图
              matrixSet: 'c', // c: 经纬度投影 w: 球面墨卡托投影
              style: "default",
              crossOrigin: 'anonymous', // 解决跨域问题 如无该需求可不添加
              format: "tiles", //请求的图层格式，这里指定为瓦片格式
              wrapX: true, // 允许地图在 X 方向重复（环绕）
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions: resolutions,
                matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
              })
            })
          }),
          // 标注
          new TileLayer({
            source: new WMTS({
              url: `http://t{0-6}.tianditu.com/cva_c/wmts?tk=${TIAN_DI_KEY}`,
              layer: 'cva', //矢量注记
              matrixSet: 'c',
              style: "default",
              crossOrigin: 'anonymous',
              format: "tiles",
              wrapX: true,
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions: resolutions,
                matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
              })
            })
          })
        ],
        view: new View({
          center: [120.585999,31.297300],
          projection: projection,
          zoom: 12,
          maxZoom: 17,
          minZoom: 1
        }),
        //加载控件到地图容器中
        controls: defaultControls({
          zoom: false,
          rotate: false,
          attribution: false
        })
      });
      this.map.addLayer(this.pointLayer);
      let popupBox = document.getElementById('popup-box');
      let popupContent = document.getElementById('popup-content');
      let closeButton = document.getElementById('close-button')
      let overlay = new Overlay({
        element: popupBox,
        autoPan: {
          animation: {
            duration: 250,
          },
        },
      });
      this.map.addOverlay(overlay);
      // 添加地图点击事件
      this.map.on('singleclick', (evt) => {
        let lonLat = evt.coordinate;
        popupContent.innerHTML = `<div>经度：${lonLat[0]}</div><div>纬度：${lonLat[1]}</div>`;
        overlay.setPosition(lonLat);
      });
      // 关闭弹出框的事件处理
      closeButton.addEventListener('click', () => {
        overlay.setPosition(undefined); // 关闭弹出框
      });
    },
    querySearchAsync(queryString, cb){
      if (queryString) {
        const params = {
          postStr: JSON.stringify({
            keyWord: queryString,
            level: 18,
            //左下角和右上角经纬度，形成一个矩形区域，只在这个区域里面搜索
            mapBound: '120.403856,31.171395,120.949665,31.524762',
            queryType: "1",
            count: 10,
            start: 0,
          }),
          type: 'query',
          tk: TIAN_DI_KEY,
        };
        search(params).then(res=>{
          if(res.data.status.infocode === 1000 && res.data.pois){
            let list = res.data.pois;
            this.options = list;
            for (let i = 0; i < list.length; i++) {
              this.options[i].value = list[i].name;
            }
          }else {
            this.options = [];
            this.$message.error("查询无结果");
          }
          cb(this.options);
        })
      } else {
        this.options = [];
        cb(this.options);
      }
    },
    searchAddress(val){
      if (!val) {
        return;
      }
      let lonLatArr = val.lonlat.split(",");
      this.form = {
        lon: lonLatArr[0],
        lat: lonLatArr[1],
        address:val.address,
      };
      let coordinates = [this.form.lon,this.form.lat];
      //清除之前的点位
      if(this.feature){
        this.pointLayer.getSource().removeFeature(this.feature);
      }
      this.addPoints(coordinates);
      // 设置新的中心和缩放级别
      this.map.getView().setCenter(coordinates); // 设置中心
      this.map.getView().setZoom(17); // 设置缩放级别（已经定义为13）
    },
    /**
     * 根据经纬度坐标添加自定义图标 支持base64
     */
    addPoints(coordinate) {
      // 创建feature要素，一个feature就是一个点坐标信息
      this.feature = new Feature({
        geometry: new Point(coordinate),
      });
      // 设置要素的图标
      this.feature.setStyle(
          new Style({
            // 设置图片效果
            image: new Icon({
              src: 'http://api.tianditu.gov.cn/img/map/markerA.png',
              // anchor: [0.5, 0.5],
              scale: 1.2,
            }),
          })
      );
      // 要素添加到地图图层上
      this.pointLayer.getSource().addFeature(this.feature);
    },
  }
}
</script>
<style scoped>
#map-container {
  width: 100%;
  height: 100vh;
}
.popup-box {
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 20px;
  z-index: 1000;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
  max-width: 300px;
  font-family: 'Arial', sans-serif;
  position: absolute;
  transform: translate(-50%, -100%); /* 使弹出框上移并居中 */
}

/* 添加箭头样式 */
.popup-box::after {
  content: "";
  position: absolute;
  top: 100%; /* 箭头位于弹出框的底部 */
  left: 50%; /* 箭头横向居中 */
  margin-left: -6px; /* 调整箭头与弹出框的间距 */
  border-width: 6px; /* 箭头的大小 */
  border-style: solid;
  border-color: rgba(255, 255, 255, 0.95) transparent transparent transparent; /* 箭头的颜色 */
}

.close-button {
  background: none;
  color: gray;
  border: none;
  font-size: 20px;
  position: absolute;
  top: 10px;
  right: 10px;
  cursor: pointer;
}

.popup-content {
  width: 240px;
  margin-top: 10px;
  font-size: 16px;
  line-height: 1.5;
}
</style>
